	package org.onejava.core.manage;

import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.RequestDispatcher;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.onejava.core.annotation.View;
import org.onejava.core.bean.Allconfig;
import org.onejava.core.bean.MContext;
import org.onejava.core.bean.ViewEntity;
import org.onejava.core.tools.ObjectTools;
import org.onejava.core.tools.ScanTool;

import com.alibaba.fastjson.JSON;
public class ViewManage extends BaseManage{
	private static ViewManage manage;
	private HashMap<String,ViewEntity> entityMap;
    private static  Log log = LogFactory.getLog(ViewManage.class);  
    private ViewManage(){}
    
    /**
     * 获取单例
     * @return
     */
    public static ViewManage getMamage(){
    	if(null==manage){
    		manage = new  ViewManage();
		}
		return manage;
    }
    
	/**
	 * 初始化
	 * @param packagePath
	 * @throws Exception
	 */
	public void intiMap(String packagePath) throws Exception{
		if(null!=entityMap){
			return;
		}
		//扫描出所有View路径
		ScanTool sacntool = new ScanTool();
		List<String> list = sacntool.getAllClassName(Allconfig.truePath,packagePath);
		log.info("开始在路径<"+packagePath+">下扫描View");
		entityMap = new HashMap<String, ViewEntity>();
		
		for(int i=0;i<list.size();i++){
			Object actionObj = ObjectTools.getTheObject(list.get(i));
			Method method=null;
			try {
				method = ObjectTools.getMethod(actionObj, Allconfig.defaultMethod, MContext.class);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				log.warn("扫描到的类<"+list.get(i)+">没有有效的<"+Allconfig.defaultMethod+">方法");
				continue;
			}
			Map interceptorInfoMap = getViewInfo(method);
			String interceptorName = (String) interceptorInfoMap.get("name");
			if(null==interceptorName||"".equals(interceptorName)){
				log.warn("类<"+list.get(i)+">没有有效的注解信息,无法载入视图MAP中");
				continue;
			}
			ViewEntity ve = new ViewEntity(interceptorName,actionObj,method);
			
			//使用Ioc插件注入变量
			setBean(ve);
			Object obj =entityMap.put(interceptorName, ve);
			if(null!=obj){
				throw new Exception("视图:Name:"+interceptorName+">>>ClassPath:"+list.get(i)+"有重复 视图加载STOP");
			}
			log.info("视图:"+interceptorName+">>>ClassPath:"+list.get(i)+"载入成功");			
		}
	} 
	
	/**
	 * 处理view
	 * @param context
	 * @throws Exception 
	 */
	public void doView(MContext context) throws Exception{
		RequestDispatcher dispatcher=null;
		String result = context.getResult();
		if("404".equals(result)||"".equals(result)||null==result){
			result=Allconfig.noFindPage;
			if("404".equals(result)){
				context.getResponse().setStatus(404);
				return;
			}	
		}
		if("error".equals(result)){	
			result=Allconfig.errorPage;
		}
		String results[] =result.split(",");		
		if(results.length<=1){
			doValues(context);
			context.getRequest().getRequestDispatcher("/"+Allconfig.pageRoot+"/WEB-INF/"+result+".jsp").forward(context.getRequest(), context.getResponse());
			return;
		}else{
			//Redirect跳转
			if("redirect".equals(results[0])){
				context.getResponse().sendRedirect(results[1]);
				return;
			}else
			//Forward跳转
			if("forward".equals(results[0])){
				doValues(context);
				context.getRequest().getRequestDispatcher(results[1]).forward(context.getRequest(), context.getResponse());
				return;
			}else
			//Json视图处理
			if("json".equals(results[0])){
				String jsonString = JSON.toJSONString(context.getResultMap().get(results[1]));
				PrintWriter out=null;
				try{
					context.getResponse().setContentType("text/html;charset="+Allconfig.Charact);
					//输出返回字符串1
					out = context.getResponse().getWriter();
					out.print(jsonString);
				} catch (Exception e) {
					throw new Exception(e);
				}finally{
					if(out!=null){
						out.flush();
						out.close();
					}
				}
				return;
			}else{
			//自定义视图处理
				ViewEntity ve = entityMap.get(results[0]);
				if(null==ve){
					log.debug("无法找到自定义视图："+results[0]);
				}else{
					doEntity(ve,context);
					return;
				}
			}
		}
		if(null==dispatcher){
			context.getRequest().getRequestDispatcher("/"+Allconfig.noFindPage).forward(context.getRequest(), context.getResponse());
		}
		return;
	}
	
	private void doEntity(ViewEntity ve,MContext context)throws Exception{
		try {
			ObjectTools.invokeObject(ve.getObj(), ve.getMethod(), context);
		} catch ( InvocationTargetException e) {
			// TODO Auto-generated catch block
			//log.error("发生了错误", e.getTargetException());
			throw new Exception(e.getTargetException());
		}
		//log.info("自定义视图:<"+ve.getName()+">执行完毕");
	}
	
	private void doValues(MContext context){
		Map map =context.getResultMap();
		if(null==map){
			return;
		}
		Iterator it=map.entrySet().iterator();           
		while(it.hasNext()){
	        Map.Entry entry = (Map.Entry)it.next();           
	        String key=entry.getKey().toString();
	        Object value=entry.getValue();
	        context.getRequest().setAttribute(key, value);
		}
	}
	/**
	 * 获取view的注解信息
	 * @param msa
	 * @return Map{befores，afters}
	 */
	private Map getViewInfo(Method msa){
		View annotation = msa.getAnnotation(View.class);
		Map map  = new HashMap();
		if(null!=annotation){
			String name = annotation.name();
			map.put("name", name);
		}else{
			map.put("name", "");
		}
		return map;
	} 
}
